package com.eunion.core;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * bootstrap and table page.
 * 
 * @param <T>
 * 
 * @version 2015-8-22
 */
public class PageData<T> {

    // private Logger logger = LoggerFactory.getLogger(getClass());

    private Logger LOG = LoggerFactory.getLogger(getClass());

    public static final int PAGE_SIZE_MAX = 500;// 每页最大记录数限制

    public static final int PAGE_SIZE_DEFAULT = 5;// 每页默认记录数

    public static final int DEFAULT_0 = 0;

    public static final int DEFAULT_1 = 1;

    public static final long DEFAULT_0l = 0L;

    // private String searchBy = "";// 查找属性名称
    // private String keyword;// 查找关键字
    // private String orderBy = "id";// 排序字段
    // private OrderType orderType = OrderType.desc;// 排序方式

    private List<T> rows;// 数据

    private List<T> chartData;// 数据

    private T obj;

    private String rowData;// 数据

    private Integer limit;// pageSize = 10 每页记录数

    private Integer pageSize;// 当前页码 同limit

    private Integer offset;// offset是最后的数目

    private Integer pageCount;// 总共页码

    private Integer pageNumber;// 当前页码

    private long total;// 总数

    private String search;

    private String order; // "desc"

    private String sort;

    private Map<String, String> searchMap = new HashMap<String, String>();

    private List<String> searchList = new ArrayList<String>();

    private List<PageConditions> conditions = null;

    public PageData() {
        // this.calculate();
    }

    public PageData(PageParams pages) {
        if (null != pages) {
            setPageNumber(null == pages.getPageNumber() ? DEFAULT_1 : pages.getPageNumber());
            setPageSizeLimit(null == pages.getPageSize() ? PAGE_SIZE_DEFAULT : pages.getPageSize());
        } else {
            setPageNumber(DEFAULT_1);
            setPageSizeLimit(PAGE_SIZE_DEFAULT);
        }
        this.calculate();
    }

    public PageData(long total, List<T> datas) {
        this.total = total;
        this.rows = datas;
        this.calculate();
    }

    public void calculate() {
        // 设置默认pagesize 或称limit
        if (null == getLimit() || getLimit() < PAGE_SIZE_DEFAULT) {
            setPageSizeLimit(PAGE_SIZE_DEFAULT);
        }
        // 确保，数据合法
        if (getLimit() >= PAGE_SIZE_MAX) {
            setPageSizeLimit(PAGE_SIZE_MAX);
        }
        if (null == getPageSize()) {
            setPageSize(getLimit());
        }

        if (null == getPageNumber()) {
            setPageNumber(DEFAULT_1);
        }
    }

    public String getRowData() {
        if (null == this.rows) {
            return "[]";
        }
        return rowData;
    }

    public void setRowData(String rowData) {
        this.rowData = rowData;
    }

    public Map<String, String> getSearchMap() {
        return searchMap;
    }

    public void setSearchMap(Map<String, String> searchMap) {
        this.searchMap = searchMap;
    }

    private void setPageSizeLimit(Integer pagesize) {
        this.pageSize = pagesize;
        this.limit = pagesize;
    }

    /**
     * 是否降序.
     */
    public boolean isDesc() {
        if ("desc".equalsIgnoreCase(order)) {
            return true;
        }
        return false;
    }

    public Integer getLimit() {
        return limit;
    }

    public void setLimit(Integer limit) {
        this.pageSize = limit;
        this.limit = limit;
    }

    public Integer getOffset() {
        return offset;
    }

    public void setOffset(Integer offset) {
        this.offset = offset;
    }

    public String getOrder() {
        return order;
    }

    public void setOrder(String order) {
        this.order = order;
    }

    public String getSort() {
        return sort;
    }

    public void setSort(String sort) {
        this.sort = sort;
    }

    public String getSearch() {
        return search;
    }

    public void setSearch(String search) {
        this.search = search;
    }

    // public Map<String, Object> getSearchparams() {
    // return searchparams;
    // }
    //
    // public void setSearchparams(Map<String, Object> searchparams) {
    // this.searchparams = searchparams;
    // }

    public List<T> getRows() {
        return rows;
    }

    public void setRows(List<T> rows) {
        this.rows = rows;
        // setRows(rows,null);
    }
    //
    // public void setRows(List<T> rows,JsonConfig cfg) {
    // this.rows = rows;
    // if(cfg == null){
    // cfg = new JsonConfig();
    // }
    // //net.sf.json.JSONException: java.lang.reflect.InvocationTargetException异常
    // cfg.setExcludes(new String[]{"handler","hibernateLazyInitializer"});
    //
    // //过滤关联，避免死循环net.sf.json.JSONException: java.lang.reflect.InvocationTargetException
    // cfg.setJsonPropertyFilter(new PropertyFilter() {
    // public boolean apply(Object source, String name, Object value) {
    // if(name.equals("addressGroup")||name.equals("user")||name.equals("createTime")||name.equals("birthday")) {
    // return true;
    // } else {
    // return false;
    // }
    // }
    // });
    //
    // //javabean里出现循环调用啦，赶快用excludes干掉parent或者children
    // cfg.setExcludes(new String[]{"sysUri","sysUris","sysRoleUriLinks"});
    // //net.sf.json.JSONException: java.lang.reflect.InvocationTargetException日期格式转化出错
    // // cfg.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT);
    // cfg.registerJsonValueProcessor(Date.class, new DateJsonProcessor("yyyy-MM-dd hh:mm:ss"));
    //
    // JSONArray json = JSONArray.fromObject(this.rows);
    // this.rowData = json.toString();
    // }

    public Integer getPageSize() {
        return pageSize;
    }

    public void setPageSize(Integer pageSize) {
        this.limit = pageSize;
        this.pageSize = pageSize;
    }

    public long getTotal() {
        return total;
    }

    public void setTotal(long total) {
        this.total = total;
    }

    // @JsonIgnore
    public void setTotal(Integer total) {
        this.total = total == null ? DEFAULT_0l : total.longValue();
    }

    public Integer getPageCount() {
        return pageCount;
    }

    public void setPageCount(Integer pageCount) {
        this.pageCount = pageCount;
    }

    // @JsonIgnore
    public void setPageCount(Long pageCount) {
        this.pageCount = (pageCount == null ? DEFAULT_0 : pageCount.intValue());
    }

    public Integer getPageNumber() {
        return pageNumber;
    }

    public void setPageNumber(Integer pageNumber) {
        this.pageNumber = pageNumber;
    }

    public List<PageConditions> getConditions() {
        if (this.conditions != null) {
            return this.conditions;
        } else {
            conditions = new ArrayList<PageConditions>();
        }

        // "name,like,string": "zhangsan"
        LOG.debug("add search Map : {}", this.searchMap);
        // "name,like,string,zhangsan"
        LOG.debug("add search List : {}", this.searchList);
        // 根据searchMap设置condition
        if (this.searchMap != null && this.searchMap.size() > 0) {
            Map<String, String> simpleSearchMap = new HashMap<String, String>();
            for (Map.Entry<String, String> entry : searchMap.entrySet()) {
                String[] key = entry.getKey().split(",");
                if (key != null && key.length >= 3) {
                    simpleSearchMap.put(key[0], entry.getValue());
                    if (StringUtils.isNotEmpty(entry.getValue())) {
                        PageConditions pc = new PageConditions();
                        pc.setKey(key[0]);
                        pc.setValue(entry.getValue().trim());// 清理前后空格
                        pc.setOperator(key[1]);
                        pc.setType(key[2]);
                        LOG.debug("add search condition : {}", pc);
                        conditions.add(pc);
                    }
                }
            }
            this.searchMap = simpleSearchMap;
        } else if (this.searchList != null && this.searchList.size() > 0) {
            for (String entry : searchList) {
                String[] key = entry.split(",");
                if (key != null && key.length >= 4 && StringUtils.isNotEmpty(key[3])) {
                    PageConditions pc = new PageConditions();
                    pc.setKey(key[0]);
                    pc.setValue(key[3].trim());// 清理前后空格
                    pc.setOperator(key[1]);
                    pc.setType(key[2]);
                    LOG.debug("add search condition : {}", pc);
                    conditions.add(pc);
                }
            }
        }

        return conditions;
    }

    public void setConditions(List<PageConditions> conditions) {
        this.conditions = conditions;
    }

    public List<String> getSearchList() {
        return searchList;
    }

    public void setSearchList(List<String> searchList) {
        this.searchList = searchList;
    }

    public T getObj() {
        return obj;
    }

    public void setObj(T obj) {
        this.obj = obj;
    }

    public List<T> getChartData() {
        return chartData;
    }

    public void setChartData(List<T> chartData) {
        this.chartData = chartData;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
    }

}
